package infixupn;

public class Infix{
  /**Wandelt einen Infix-Term um in einen UPN-Term.
   * @param infix der Infixterm
   * @return den UPN-Term
   */
  public static Queue upnFromInfix(Queue infix){
    Stack operatorparkplatz=new Stack();
    Queue upnqu=new Queue();
    while(!infix.empty())
      if(infix.numberNext()) upnqu.put(infix.takeDouble());
      else{
        String str=infix.takeString();
        if(str.equals(")"))
          while(!(str=operatorparkplatz.pullString()).equals("("))
            upnqu.put(str);
        else{
          while(!stronger(str, operatorparkplatz))
            upnqu.put(operatorparkplatz.pullString());
          operatorparkplatz.push(str);
        }
      }
    while(!operatorparkplatz.empty())
      upnqu.put(operatorparkplatz.pullString());
    return upnqu;
  }

  /**Entscheidet, ob der neue Operator auf den Stack kommt und dort alles um
   * eine Stufe unterdrücken darf. Das ist dann der Fall, wenn nichts oder '('
   * auf dem Stack ist, oder wenn ein '(' kommt, oder ein stärkerer Operator
   * kommt als oben auf dem Stack liegt.
   * @param op der neu ankommende Operator
   * @param ops die gestackten bisherigen Operatoren
   * @return true, genau dann, wenn der neue Operator auf den Stack kommt.
   */
  private static boolean stronger(String op, Stack ops){
    if(ops.empty() || op.equals("(")) return true;
    String top=ops.pullString(); ops.push(top);// hole oberstes Stackzeichen
    if(top.equals("(")) return true;
    if(top.equals("*") || top.equals("/")) return false;
    else return op.equals("*") || op.equals("/");
  }

  public static void main(String[] args){
    // Aufruf: java Infix "( 2 + 3 ) * 4"
    // Stelle Eingabe als Queue bereit. Da fehlt es noch sehr an Luxus,
    // weil der Benutzer alles durch Leerzeichen trennen muss.
    Queue infixqu=new Queue();
    for(String s: args[0].split(" "))//trenne bei Leerzeichen
      try{
        double zahl=Double.parseDouble(s);
        infixqu.put(zahl);
      } catch(Exception ex){
        infixqu.put(s);
      }
    System.out.println("infixqu="+infixqu);
    Queue upnqu=upnFromInfix(infixqu);
    System.out.println(UPN.upn(upnqu));
  }
}
